/*
 * Lab08A2.cpp
 * Example with dynamic memory allocation and exceptions
 *
 *  Created on: Apr 10, 2014
 *      Author: Anthony Varghese
 */

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::ostream;

class Data{
public:
	Data() : size(0), data(nullptr), name("Data")	{
		cout << "Default constructor: " << *this;
	}
	Data(int d): size(d), data(nullptr), name("Data") {
		cout << "Alternate constructor: " << *this;
		if (size > 0){
			data = new double[size];
			for (int i=0; i<size; i++)
				data[i] = size;
		}
	}
	Data(string n): size(0), data(nullptr), name(n) {
		cout << "Alternate constructor: " << *this;
	}
    ~Data()	{
    	cout << "Destructor for Data: " << *this;
    	delete[] data;
    }
    Data(const Data& o): size(o.size), name(o.name){
    	cout << "Copy constructor: " << *this;
    	if (size <= 0)
    		return;
    	delete[] data;  data = new double[size];
    	for (int i=0; i<size; i++) data[i] = o.data[i];
    }
    friend ostream& operator<<(ostream& os, const Data& d);
private:
    int size;
    double* data;
    string name;
};

ostream& operator<<(ostream& os, const Data& d){
	os << "  Data: " << " " << d.name << endl;	return os;
}

#include <memory>  // for unique_ptr

int main(){
    cout << "CSIS 237 Lab 8 - Example with dynamic memory allocation and exceptions" << endl;

    Data d("d");
    Data* dheap;
    int number = 4;

    try {
    	dheap = new Data("dheap");
    	std::unique_ptr<Data> dsmart( new Data("dsmart") );

    	cout << endl;
    	cout << "    d object:      " << d;
    	cout << "    dheap object:  " << *dheap;
    	cout << "    dsmart object: " << *dsmart;
    	cout << endl;
    	if (number == 5)
    		throw "Bad Number";

    	delete dheap;
    } catch ( ... ) {
    	cout << "Caught an exception!" << endl;
    }
    cout << "... done" << endl;
}
